﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using Daco.Web.UI;
using Daco.Security;
using Daco.Web.Config;
using Daco.Web.Data.Providers;

namespace Daco.Web
{
    public enum ENickType
    {
        Yahoo,
        Skype,
        Live,
        GTalk
    }
    public struct DACONick
    {
        public int NickID;
        public string NickName;
        public string Name;
        public string Title;
        public ENickType NickType;

        public DACONick(string nickName, string name, string title, ENickType nickType)
        {
            this.NickID = 0;
            this.NickName = nickName;
            this.Name = name;
            this.Title = title;
            this.NickType = nickType;
        }

        public DACONick(int nickID, string nickName, string name, string title, ENickType nickType)
            : this(nickName, name, title, nickType)
        {
            this.NickID = nickID;
        }
    }

    public class CWeb : CBizObject
    {
        public int SettingID { get; private set; }
        public string SiteUrl { get; set; }
        public string SiteName { get; set; }
        public string SiteDescription { get; set; }
        public string Address { get; set; }

        internal CWeb()
        {
        }

        internal CWeb(int settingID, string siteUrl, string siteName, string siteDescription)
        {
            this.SettingID = settingID;
            this.SiteName = siteName;
            this.SiteUrl = siteUrl;
            this.SiteDescription = siteDescription;
        }

        public static CWeb GetCurrent()
        {
            return null;
        }

        public static string ContactInfo()
        {
            string key = "DACO_GetContactInfo";
            if (Config.CSiteConfig.Current.EnableCaching && CBizObject.Cache[key] != null)
                return (string)CBizObject.Cache[key];
            else
            {
                string contactInfo = Data.Providers.CWebProvider.Instance.GetContactInfo();
                CacheData(key, contactInfo);

                return contactInfo;
            }
        }

        /// <summary>
        /// Cache the input data, if caching is enabled
        /// </summary>
        protected static void CacheData(string key, object data)
        {
            if (Config.CSiteConfig.Current.EnableCaching && data != null)
            {
                CBizObject.Cache.Insert(key, data, null,
                   DateTime.Now.AddSeconds(Config.CSiteConfig.Current.CacheDuration), TimeSpan.Zero);
            }
        }

        public static DataRowCollection GetProfileList()
        {
            string key = "DACO_CompanyProfiles_GetProfileList";
            if (Config.CSiteConfig.Current.EnableCaching && CBizObject.Cache[key] != null)
                return (DataRowCollection)CBizObject.Cache[key];
            else
            {
                DataRowCollection profileList = Data.Providers.CWebProvider.Instance.GetProfileList();
                CacheData(key, profileList);
                return profileList;
            }
        }

        public static DataRow GetDefaultProfile()
        {
            return GetProfile(string.Empty, true);
        }

        public static DataRow GetProfile(string id)
        {
            return GetProfile(id, false);
        }

        internal static DataRow GetProfile(string id, bool primary)
        {
            string key = "DACO_GetCompanyProfile_" + id + "_" + primary.ToString();
            if (Config.CSiteConfig.Current.EnableCaching && CBizObject.Cache[key] != null)
                return (DataRow)CBizObject.Cache[key];
            else
            {
                DataRow profile = Data.Providers.CWebProvider.Instance.GetProfile(id, primary);
                CacheData(key, profile);

                return profile;
            }
        }

        public static bool AddProfile(string id, string body, bool primary)
        {
            int retv = Data.Providers.CWebProvider.Instance.AddProfile(id, body, primary);
            return retv > 0;
        }

        public static List<CMenuItem> GetMenus()
        {
            string key = "DACO_GetMenus";
            if (Config.CSiteConfig.Current.EnableCaching && CBizObject.Cache[key] != null)
                return (List<CMenuItem>)CBizObject.Cache[key];
            else
            {
                List<CMenuItem> menus = new List<CMenuItem>();
                DataTable tblMenu = Data.Providers.CWebProvider.Instance.GetMenuTable();
                if (tblMenu != null && tblMenu.Rows.Count > 0)
                {
                    foreach(DataRow row in tblMenu.Rows)
                        menus.Add(new CMenuItem(
                            (int)row["MenuID"],
                            Convert.ToInt32(row["ParentMenuID"]),
                            row["Name"].ToString(),
                            row["Title"].ToString(),
                            row["ImageUrl"].ToString(),
                            row["RelativeUrl"].ToString(),
                            (int)row["Priority"]));
                }

                List<CMenuItem> orderedMenus = new List<CMenuItem>();
                if (menus.Count > 0)
                {
                    // Re-order menu
                    foreach (CMenuItem item in menus)
                        if (item.ParentMenuItemID > 0)
                        {
                            CMenuItem parent = Find(orderedMenus, new CMenuItem(item.ParentMenuItemID));

                            if (parent == null) throw new InvalidProgramException("Invalid menu structure");
                            parent.ChildMenuItems.Add(item);
                        }
                        else
                        {
                            int index = orderedMenus.FindIndex(delegate(CMenuItem match)
                            {
                                return match.Priority > item.Priority;
                            });

                            orderedMenus.Insert(index >= 0 ? index : 0, item);
                        }
                }
                return menus;
            }
        }

        internal static CPermission GetUserPermission(ISitePage page)
        {
            string key = "DACO_Permission_UserPermission_" + page.Module + "_" + page.Name + "_" + page.CurrentUser.UserName;
            if (Config.CSiteConfig.Current.EnableCaching && CBizObject.Cache[key] != null)
                return (CPermission)CBizObject.Cache[key];
            else
            {
                int[] pValues = Data.Providers.CWebProvider.Instance.GetUesrPermission(page.Module, page.Name, page.CurrentUser.UserName);
                int p = 0;
                
                for (int i = 0; i < pValues.Length; i++) p |= pValues[i];

                CPermission userPermission = new CPermission(p);
                CacheData(key, userPermission);
                return userPermission;
            }
        }

        internal static void AddPage(ISitePage page)
        {
            Data.Providers.CWebProvider.Instance.AddPage(page.Module, page.Name, page.Description, page.Permission.BitValue);
        }

        internal static bool UpdatePage(string module, string name, string description)
        {
            bool success = false;

            success = Data.Providers.CWebProvider.Instance.UpdatePage(module, name, description);

            return success;
        }

        private static CMenuItem Find(List<CMenuItem> categoryList, CMenuItem match)
        {
            CMenuItem foundMenuItem = null;

            foreach (CMenuItem item in categoryList)
            {
                if (item.MenuItemID == match.MenuItemID)
                {
                    foundMenuItem = item;
                    break;
                }
                else if (item.ChildMenuItems != null && item.ChildMenuItems.Count > 0)
                {
                    if ((foundMenuItem = Find(item.ChildMenuItems, match)) != null)
                        break;
                }
            }

            return foundMenuItem;
        }

        public static string GetFooter()
        {
            string key = "DACO_Web_GetFooter";
            if (CSiteConfig.Current.EnableCaching && CBizObject.Cache[key] != null)
                return (string)CBizObject.Cache[key];
            else
            {
                string content = CWebProvider.Instance.GetFooter();
                if (!string.IsNullOrEmpty(content))
                    CacheData(key, content);
                return content;
            }
        }

        public static bool UpdateFooter(string content)
        {
            bool success = CWebProvider.Instance.UpdateFooter(content);

            if (success)
                CBizObject.PurgeCacheItems("DAC_Web_GetFooter");            // Clear cache

            return success;
        }
    }
}
